<?php
namespace App\Service;

use App\Helper\TimeHelper;
use App\Model\BmrUserModel;
use App\Model\UserBuilderModel;
use App\Service\BMR\BMR_Metabolize;
use App\Service\BMR\Metabolize\BasialMetabolize;
use App\Service\BMR\Metabolize\Man;
use App\Service\BMR\Metabolize\Woman;
use App\Service\BMR\Nutrition\Carbohydrate;
use App\Service\BMR\Nutrition\Fat;
use App\Service\BMR\Nutrition\Protein;

class UserBuilderService {

    /**更新或者新增
     * @param BmrUserModel $userModel
     * @param array $params
     * [ ...数据表字段名 ]
     * @return bool
     */
    public function updateOrCreate(BmrUserModel &$userModel, array $params) {
        $userBuilder = $userModel->lastBuilder()->first();
        $now = date('Y-m-d H:i:s');
        $data =  [
            'bmr_user_id'=> $userModel->id,
            'cycle' => number_format($params['cycle'] ?? ($userBuilder->cycle ?? ''), 2, '.', ''),
            'weight' => number_format($params['weight'] ?? ($userBuilder->weight ?? ''), 2, '.', ''),
            'addWeight' => number_format($params['addWeight'] ?? ($userBuilder->addWeight ?? ''), 2, '.', ''),
            'height' => number_format($params['height'] ?? ($userBuilder->height ?? ''), 2, '.', ''),
            'age' => number_format($params['age'] ?? ($userBuilder->age ?? ''), 2, '.', ''),
            'totalHot' => number_format($params['totalHot'] ?? ($userBuilder->totalHot ?? 0), 2, '.', ''),
            'baseHot' => number_format($params['baseHot'] ?? ($userBuilder->baseHot ?? 0), 2, '.', ''),
            'created_at' => $now,
            'updated_at' => $now
        ];
        return UserBuilderModel::insert($data);
//        if (!$userBuilder) {
//            return UserBuilderModel::insert($data);
//        } else {
//            foreach($data as $key => $value) {
//                $userBuilder->{$key} = $value;
//            }
//            return $userBuilder->save();
//        }
    }

    /**计算用户的mbr
     * @param $params
     * [
     *      'age' => 年龄,
     *      'weight' => 体重,
     *      'height' => 身高,
     *      'cycle' => 运动周期指数,
     * ]
     * @return array
     * [
     *      'totalHot'  => '总热量',
     *      'protein'   => '蛋白质热量',
     *      'fat'       => '脂肪热量',
     *      'Carbohydrate => '碳水化合物热量'
     * ]
     */
    public function getMbr($params) {
        $age = $params['age'] ?? 0;
        $weight = $params['weight'] ?? 0;
        $height = $params['height'] ?? 0;
        $addWight = $params['addWeight'] ?? 0;
        $cycle = $params['cycle'] ?? 0;
        $type = $params['type'] == 1 ? BMR_Metabolize::TYPE_ADD : BMR_Metabolize::TYPE_DEL;
        //设置年龄，体重，身高
        $person = $params['sex'] == 1 ? new Man() :new Woman();
        $person = $person->setAge($age)->setWeight($weight)->setHeight($height);
        $service = new BMR_Metabolize();

        $return = [];
        $total = 0;
        //代谢热量计算
        $return['totalHot'] = $total = $service->setPerson($person)->totalHot( new BasialMetabolize(), $cycle, $service->getWeightHot($type, $addWight));
        //食物各个营养
        $return = array_merge($return, [
            'protein'   =>  (new Protein())->setTotalHot($total)->display(),    //蛋白质
            'fat'       =>  (new Fat())->setTotalHot($total)->display(),        //脂肪
            'carbohydrate'=>  (new Carbohydrate())->setTotalHot($total)->display() //营养
        ]);
        return $return;
    }

    /**获取用户健身食物的总营养热量
     * @param UserBuilderModel $userBuilderModel
     * @return array
     */
    public function getBuilderMbr(UserBuilderModel $userBuilderModel) {
        return $this->getMbr(
            array_merge(
            $userBuilderModel->toArray(),
            [
                'sex'  => $userBuilderModel->user()->first()->sex,
                'type' => $userBuilderModel->weight > 0 ? BMR_Metabolize::TYPE_ADD : BMR_Metabolize::TYPE_DEL
            ])
        );
    }

    /**获取用户评测后 某天的食物营养剩余量
     * @param UserBuilderModel $userBuilderModel
     * @param $date 某天
     * @return array
     */
    public function getBuilderRestHot(UserBuilderModel $userBuilderModel, $date) {
        $foods = $this->getFoodsHot($userBuilderModel, $date);
        $totalHot= $this->getBuilderMbr($userBuilderModel);
        return [
            'totalHot'=> $totalHot,
            'foods'=> $foods,
            'rest' => [
                'protein'   => number_format($totalHot['protein'] - collect($foods)->sum(function($food){ return $food->food_protein; }), 2, '.', ''),
                'fat'       => number_format($totalHot['fat'] - collect($foods)->sum(function($food){ return $food->food_fat; }), 2, '.', ''),
                'carbohydrate'=> number_format($totalHot['carbohydrate'] - collect($foods)->sum(function($food){ return $food->food_carbohydrate; }), 2, '.', ''),
            ]
        ];
    }


    /**获取某天所需食物热量
     * @param UserBuilderModel $userBuilderModel
     * @param string $date 日期 某天的食物配置
     * @return collect
     */
    public function getFoodsHot(UserBuilderModel $userBuilderModel, string $date = '')
    {
        $foodService = new FoodService();
        $query = $userBuilderModel->foods();
        //时间范围查询
        if ($date) {
            $query = $query->whereBetween('user_food.created_at', [TimeHelper::toDay($date), TimeHelper::toDayEnd($date)]);
        }
        return $query->get()->map(function($food) use ($foodService) {
            //获取食物营养热量
            $food->food_fat = $foodService->getFatHot($food->food_fat);
            $food->food_protein = $foodService->getProteinHot($food->food_protein);
            $food->food_carbohydrate = $foodService->getCarbohydrateHot($food->food_carbohydrate);
            return $food;
        });
    }

}

